package socket

import (
	"sync"
	"gitee.com/DengAnbang/goutils/loge"
	"gitee.com/DengAnbang/Computation/src/code"
	"gitee.com/DengAnbang/Computation/src/bean"
	"gitee.com/DengAnbang/Computation/src/api"
	"errors"
)

var SocketManage Manage

func init() {
	SocketManage = Manage{Conns: make(map[string]ResponseAble)}
}

type Manage struct {
	heartbeat   bool                    //心跳
	Lock        sync.RWMutex            //互斥(保证线程安全)
	SocketName  string                  //客户端Socket名称
	MaxLifeTime int64                   //垃圾回收时间
	Conns       map[string]ResponseAble //保存packet的指针[SocketID] = packet
}

func SendMessageToKey(key string, msg interface{}) {
	SocketManage.Lock.Lock()
	defer SocketManage.Lock.Unlock()
	conn, ok := SocketManage.Conns[key]
	if ok {
		conn.SendMessageToConn(msg)
	} else {
		loge.W("发送消息失败,%s不存在", key)
	}
}

type ResponseAble interface {
	GetId() string
	SetId(id string)
	Response(err error, messageType int)
	SendMessageToConn(msg interface{}) (err error)
}

func Dispense(message *bean.RequestData, conn ResponseAble) {
	defer func() {
		i := recover()
		if err, ok := i.(error); ok {
			conn.Response(err, 0)
		}
	}()
	var parameters = message.Data
	switch message.Type {
	//公共部分
	case code.PCAuthenticationLic:
		conn.Response(api.PCAuthenticationLic(parameters), code.PCAuthenticationLic)
	case code.PcTypeRegister:
		conn.Response(api.UserRegisterSocket(parameters), code.PcTypeRegister)
	case code.PcTypeLogin:
		userId, err := api.UserLoginSocket(parameters)
		lastCon := Register(userId, conn)
		if lastCon != nil {
			succeedMessage := bean.NewSucceedMessage("")
			succeedMessage.Type = code.TypeOtherLogin
			lastCon.SendMessageToConn(succeedMessage)
		}
		conn.Response(err, code.PcTypeLogin)
		//树相关的
	case code.TypeTreeCreate:
		conn.Response(api.CreateTreeSocket(parameters, conn.GetId()), code.TypeTreeCreate)
	case code.TypeTreeAddNode:
		conn.Response(api.AddTreeNodeSocket(parameters, conn.GetId()), code.TypeTreeAddNode)
	case code.TypeTreeDeleteNode:
		conn.Response(api.DeleteTreeNodeSocket(parameters), code.TypeTreeDeleteNode)
	case code.TypeTreeSelectNodeList:
		conn.Response(api.SelectTreeNodeListSocket(parameters), code.TypeTreeSelectNodeList)
	case code.TypeRenameNode:
		conn.Response(api.RenameTreeNodeSocket(parameters), code.TypeRenameNode)
	case code.TypeGetMyTreeNode:
		conn.Response(api.GetMyTreeNodeSocket(parameters, conn.GetId()), code.TypeGetMyTreeNode)
	case code.TypeGetUserTreeList:
		conn.Response(api.GetUserTreeListSocket(parameters, conn.GetId()), code.TypeGetUserTreeList)
		//模板相关的
	case code.TypeTemplateCreate:
		conn.Response(api.AddTemplateNodeSocket(parameters), code.TypeTemplateCreate)
	case code.TypeTemplateAmend:
		conn.Response(api.AmendTemplateNodeSocket(parameters), code.TypeTemplateAmend)
	case code.TypeTemplateSelect:
		conn.Response(api.SelectTemplateListSocket(parameters), code.TypeTemplateSelect)
	case code.TypeTemplateDeleteByID:
		conn.Response(api.DeleteTemplateByIDSocket(parameters), code.TypeTemplateDeleteByID)
	case code.TypeTemplateDeleteByNode:
		conn.Response(api.DeleteTemplateByNodeSocket(parameters), code.TypeTemplateDeleteByNode)
		//模型相关
	case code.TypeModelBeanList:
		conn.Response(api.GetModelBeanListSocket(parameters), code.TypeModelBeanList)
	case code.TypeModelBean:
		conn.Response(api.GetModelBeanSocket(parameters), code.TypeModelBean)
	case code.TypeModelSelectTree:
		conn.Response(api.SelectModelTreeSocket(parameters), code.TypeModelSelectTree)
	case code.TypeModelNodeAddition:
		conn.Response(api.SelectModelNodeAdditionSocket(parameters), code.TypeModelNodeAddition)
	default:
		conn.Response(errors.New("未知类型错误"), 0)
	}
}
